home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 1 / LSD Compendium Deluxe 1.iso / a / disk / misc / separ1.0.lha / src / serpar.c < prev   
Encoding:
C/C++ Source or Header  |  1994-05-02  |  7.6 KB  |  317 lines

  1. /* serpar.c  Copyright 1994 Matti Rintala */
  2.  
  3. /* $Id: serpar.c 1.6 1994/05/02 09:13:04 Matti_Rintala Exp Matti_Rintala $ */
  4.  
  5.  
  6. /* This program opens a very small window and then transfer all
  7.    incoming data from serial device to parallel. This continues until
  8.    the window is closed or a break is sent to the program.
  9. */
  10.  
  11. #include <dos.h>
  12.  
  13. #include <exec/types.h>
  14. #include <exec/nodes.h>
  15. #include <exec/ports.h>
  16. #include <exec/devices.h>
  17. #include <exec/io.h>
  18. #include <devices/serial.h>
  19. #include <devices/parallel.h>
  20. #include <intuition/intuition.h>
  21.  
  22. #include <proto/exec.h>
  23. #include <proto/intuition.h>
  24.  
  25. /* Version information */
  26. static const char *version_info = "$VER: SerPar 1.00 " __AMIGADATE__;
  27.  
  28. /* These are needed by SAS/C for the runback option */
  29. char *__procname = "SerPar";
  30. long __priority = -1;
  31.  
  32. /* Constants */
  33. #define BUFSIZE 512
  34.  
  35. #define DEFSERIAL "serial.device"
  36. #define DEFPARALLEL "parallel.device"
  37.  
  38. #define PORTNAME "SerPar"
  39.  
  40. #define SERIAL 1
  41. #define PARALLEL 2
  42.  
  43. /* Some global variables */
  44.  
  45. struct IOExtSer *ser_req = NULL; /* Serial device request */
  46. struct IOExtPar *par_req = NULL; /* Parallel device request */
  47. struct MsgPort *port = NULL;    /* Port for all IO */
  48. BOOL seropen = FALSE, paropen = FALSE;
  49. char *sername, *parname;
  50. struct Window *window = NULL;
  51.  
  52. int io;
  53.  
  54. BYTE buffer[BUFSIZE];        /* Buffer for data */
  55. int buflen;
  56.  
  57. /* Function prototypes */
  58.  
  59. static void errormsg(char *s);
  60. static int init(void);
  61. static void cleanup(void);
  62.  
  63. static void serial_input(void);
  64. static void parallel_output(void);
  65.  
  66. /* Usage:  serpar [input_device_name [output_device_name]]  */
  67.  
  68. void main(int argc, char **argv) {
  69.  
  70.   BOOL running = TRUE;
  71.  
  72.   /* Handle workbench arguments */
  73.   if (argc == 0) {        /* Started from WorkBench */
  74.     argc = _WBArgc;
  75.     argv = _WBArgv;
  76.   }
  77.  
  78.   /* First handle command line arguments */
  79.   if (argc > 1) {        /* At least one argument */
  80.     sername = argv[1];        /* Use 1st argument as input device name */
  81.   }
  82.   else {
  83.     sername = DEFSERIAL;
  84.   }
  85.  
  86.   if (argc > 2) {        /* At least two arguments */
  87.     parname = argv[2];        /* Use 2nd argument as output device name */
  88.   }
  89.   else {
  90.     parname = DEFPARALLEL;
  91.   }
  92.   
  93.   /* Try to initialise all */
  94.   if (!init()) {        /* If init failed */
  95.     return;            /* Quit */
  96.   }
  97.  
  98.   /* Start reading serial */
  99.   serial_input();
  100.   io = SERIAL;
  101.  
  102.   /* Main action loop */
  103.   while(running) {
  104.     struct Message *msg;
  105.  
  106.     /* Wait for message from either serial/parallel or intuition */
  107.     Wait((1<<port->mp_SigBit) | (1<<window->UserPort->mp_SigBit));
  108.  
  109.     /* Handle all events from intuition */
  110.     while (msg = GetMsg(window->UserPort)) {
  111.       if (((struct IntuiMessage *)msg)->Class ==
  112.       IDCMP_CLOSEWINDOW) { /* Window closed */
  113.     running = FALSE; /* Stop program */
  114.       }
  115.       ReplyMsg(msg);
  116.     }
  117.     
  118.     /* If serial IO has been completed */
  119.     if (io == SERIAL && CheckIO((struct IORequest *)ser_req)) {
  120.       /* Remove the completion message */
  121.       WaitIO((struct IORequest *)ser_req);
  122.       parallel_output();        /* It's time to output data to parallel */
  123.       io = PARALLEL;
  124.     }
  125.     /* If parallel IO has been completed */
  126.     else if (io == PARALLEL && CheckIO((struct IORequest *)par_req)) {
  127.       /* Remove the completion message */
  128.       WaitIO((struct IORequest *)par_req);
  129.       serial_input();        /* It's time to input data from serial */
  130.       io = SERIAL;
  131.     }
  132.   }
  133.  
  134.   /* Terminate pending IO */
  135.   switch (io) {
  136.   case SERIAL:
  137.     AbortIO((struct IORequest *)ser_req);
  138.     WaitIO((struct IORequest *)ser_req);
  139.     break;
  140.   case PARALLEL:
  141.     AbortIO((struct IORequest *)par_req);
  142.     WaitIO((struct IORequest *)par_req);
  143.     break;
  144.   default:
  145.     errormsg("No pending IO when stopped!");
  146.   }
  147.  
  148.   cleanup();            /* Clean up everything */
  149. }
  150.  
  151. /* errormsg prints an error message */
  152.  
  153. static void errormsg(char *msg) {
  154.  
  155.   static struct EasyStruct req = {
  156.     sizeof (struct EasyStruct),
  157.     NULL,
  158.     "SerPar error",
  159.     NULL,
  160.     "QUIT"};
  161.  
  162.   req.es_TextFormat = msg;
  163.   EasyRequest(NULL, &req, NULL);
  164. }
  165.  
  166. /* init() initialises everything necessary */
  167. static int init(void) {
  168.  
  169.   struct Screen *scr;
  170.  
  171.   /* Create IO port */
  172.   if ((port = CreatePort(PORTNAME, 0)) == NULL) {
  173.     errormsg("Cannot create port for IO!");
  174.     cleanup();
  175.     return FALSE;
  176.   }
  177.   
  178.   /* Create IO request block for serial */
  179.   if ((ser_req = (struct IOExtSer *)CreateExtIO(port, sizeof(struct IOExtSer)))
  180.       == NULL) {
  181.     errormsg("Cannot create serial request block!");
  182.     cleanup();
  183.     return FALSE;
  184.   }
  185.  
  186.   /* Create IO request block for parallel */
  187.   if ((par_req = (struct IOExtPar *)CreateExtIO(port, sizeof(struct IOExtPar)))
  188.       == NULL) {
  189.     errormsg("Cannot create parallel request block!");
  190.     cleanup();
  191.     return FALSE;
  192.   }
  193.  
  194.   /* Open serial device */
  195.   ser_req->io_SerFlags = SERF_7WIRE; /* Use RTS/CTS */
  196.   if (seropen = OpenDevice(sername, 0, (struct IORequest *)ser_req, 0)) {
  197.     errormsg("Cannot open input device!");
  198.     cleanup();
  199.     return FALSE;
  200.   }
  201.  
  202.   /* Open parallel device */
  203.   par_req->io_ParFlags = 0;    /* No special flags */
  204.   if (paropen = OpenDevice(parname, 0, (struct IORequest *)par_req, 0)) {
  205.     errormsg("Cannot open output device!");
  206.     cleanup();
  207.     return FALSE;
  208.   }
  209.  
  210.   /* Now set serial device parameters */
  211.   ser_req->io_SerFlags |= SERF_XDISABLED; /* No XON/XOFF */
  212.   ser_req->IOSer.io_Command = SDCMD_SETPARAMS;
  213.   DoIO((struct IORequest *)ser_req);        /* Set parameters */
  214.  
  215.   /* Parallel device doesn't need parameter changes */
  216.  
  217.  
  218.   /* Open the SerPar window */
  219.   /* First we need information on the screen */
  220.   if ((scr = LockPubScreen(NULL)) == NULL) {
  221.     errormsg("Cannot get default public screen!");
  222.     cleanup();
  223.     return FALSE;
  224.   }
  225.   /* The we open window with minimum height */
  226.   window = OpenWindowTags(NULL,
  227.               WA_Width, 100,
  228.               WA_Height, scr->WBorTop +
  229.                          scr->Font->ta_YSize + 1,
  230.               WA_IDCMP, IDCMP_CLOSEWINDOW,
  231.               WA_Flags, WFLG_CLOSEGADGET |
  232.                         WFLG_DRAGBAR |
  233.                         WFLG_DEPTHGADGET,
  234.               WA_Title, "SerPar",
  235.               WA_PubScreen, (Tag)scr,
  236.               TAG_DONE);
  237.   /* Release the screen lock */
  238.   UnlockPubScreen(NULL, scr);
  239.   if (!window) {        /* Window creation failed */
  240.     errormsg("Cannot open window!");
  241.     cleanup();
  242.     return FALSE;
  243.   }
  244.  
  245.  
  246.   /* If we are here, all is OK */
  247.   return TRUE;
  248. }
  249.  
  250.  
  251. /* cleanup() cleans up everything init() initialised */
  252. static void cleanup(void) {
  253.  
  254.   /* Close SerPar window */
  255.   if (window) {
  256.     CloseWindow(window);
  257.   }
  258.   
  259.   /* First close opened devices */
  260.   if (!seropen) {
  261.     CloseDevice((struct IORequest *)ser_req);
  262.   }
  263.   if (!paropen) {
  264.     CloseDevice((struct IORequest *)par_req);
  265.   }
  266.  
  267.   /* Then dispose of request blocks */
  268.   if (ser_req) {
  269.     DeleteExtIO((struct IORequest *)ser_req);
  270.   }
  271.   if (par_req) {
  272.     DeleteExtIO((struct IORequest *)par_req);
  273.   }
  274.  
  275.   /* Dispose of message port */
  276.   if (port) {
  277.     DeletePort(port);
  278.   }
  279. }
  280.  
  281.  
  282. /* serial_input() activates serial input */
  283. static void serial_input(void) {
  284.   
  285.   /* Characters are read to buffer */
  286.   ser_req->IOSer.io_Data = buffer;
  287.  
  288.   /* Ask for number of chars in serial */
  289.   ser_req->IOSer.io_Command = SDCMD_QUERY;
  290.   DoIO((struct IORequest *)ser_req);
  291.  
  292.   buflen = ser_req->IOSer.io_Actual;
  293.   /* If there are buffered chars, read them (max BUFSIZE) */
  294.   if (buflen > BUFSIZE) {
  295.     buflen = BUFSIZE;
  296.   }
  297.   else if (buflen == 0) {    /* Wait for at least one character */
  298.     buflen = 1;
  299.   }
  300.  
  301.   /* Now start serial read */
  302.   ser_req->IOSer.io_Length = buflen;
  303.   ser_req->IOSer.io_Command = CMD_READ;
  304.   SendIO((struct IORequest *)ser_req);    
  305. }
  306.  
  307.  
  308. /* parallel_output() activates parallel output */
  309. static void parallel_output(void) {
  310.  
  311.   /* Simply write the buffer to parallel */
  312.   par_req->IOPar.io_Data = buffer;
  313.   par_req->IOPar.io_Length = buflen;
  314.   par_req->IOPar.io_Command = CMD_WRITE;
  315.   SendIO((struct IORequest *)par_req);
  316. }
  317.